package game.units;

import game.enums.Alignment;
import game.enums.Size;
import game.mechanics.Item;
import game.referenceValues.Magic;
import game.referenceValues.Race;
import game.referenceValues.Skill;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

public class Monster extends Unit {
	
	private static Map<String, Monster> xmlMonster;

	private String Race;
	private int Challenge;
	private ArrayList<Item> Loot;
	private ArrayList<String> Attacks;
	public int movs;

	public Monster() {
		super();
		this.Loot = new ArrayList<Item>();
		this.Attacks = new ArrayList<String>();
	}
	public Monster(String Race, int Challenge, ArrayList<Item> Loot, ArrayList<String> Attacks,String name, String height, String weight, String gender,
	String deity, Size size, Alignment alignment, int level,
	int experience, int armorClass, int fortitude, int reflex,
	int will, int attackBase[], ArrayList<Attribute> attributes,
	ArrayList<Magic> magics){
		
		super(name, height, weight, gender, deity, size, alignment, level, experience, armorClass, fortitude, reflex, will, attackBase, attributes, magics);
		this.Race = Race;
		this.Challenge = Challenge;
		this.Loot = Loot;
		this.Attacks=Attacks;
	}

	public String getRace() {
		return Race;
	}

	public void setRace(String race) {
		Race = race;
	}

	public int getChallenge() {
		return Challenge;
	}

	public void setChallenge(int challenge) {
		Challenge = challenge;
	}

	public ArrayList<Item> getLoot() {
		return Loot;
	}

	public void setLoot(ArrayList<Item> loot) {
		Loot = loot;
	}

	public ArrayList<String> getAttacks() {
		return Attacks;
	}

	public void setAttacks(ArrayList<String> attacks) {
		Attacks = attacks;
	}

	@Override
	public void setAttributes() {

	}

	public static Map<String, Monster> getMonsters() {
		return xmlMonster;
	}

	// //////////////////////////////////////////////////////////////////////////////////////////
	// //////////////////////////////////////////////////////////////////////////////////////////

	public static void loadDNDMonsters() {
		// Lendo o XML
		xmlMonster = new HashMap<String, Monster>();
		try {
			FileInputStream XMLin = new FileInputStream("monsters.xml");
			SAXBuilder sb = new SAXBuilder();
			try {
				Document doc = sb.build(XMLin);
				// Recuperamos o elemento root
				Element xmlskills = doc.getRootElement();
				// Recuperamos os elementos filhos (children)
				List elements = xmlskills.getChildren();
				Iterator i = elements.iterator();

				while (i.hasNext()) {
					Element element = (Element) i.next();
					ArrayList<Item> Loot = new ArrayList<Item>();
					ArrayList<String> powers = new ArrayList<String>();
					Element el = element.getChild("Loots");
					List modElements = el.getChildren();
					Iterator j = modElements.iterator();
					while (j.hasNext()) {
						Element temp = (Element) j.next();
						Loot.add(new Item(temp.getChildText("Item"), "",
								Integer.parseInt(temp.getChildText("Quantity"))));
					}

					Element el2 = element.getChild("Powers");
					List skillElements = el2.getChildren();
					Iterator k = skillElements.iterator();
					while (k.hasNext()) {
						Element temp = (Element) k.next();
						powers.add(temp.getChildText("Name") + " "
								+ temp.getChildText("Description"));
					}
					Monster monster = new Monster();
					monster.setName(element.getChildText("Name"));
					monster.setAlignment(Alignment.valueOf(element
							.getChildText("Alignment")));
					monster.setSize(Size.valueOf(element.getChildText("Size")));
					monster.setRace((element.getChildText("Race")));
					monster.setLifePoints(Integer.parseInt((element
							.getChildText("LifePoints"))));
					monster.movs = (Integer.parseInt((element
							.getChildText("Moviments"))));
					monster.setChallenge(Integer.parseInt((element
							.getChildText("Challenge"))));
					monster.setInitiative(Integer.parseInt((element
							.getChildText("Initiative"))));
					monster.setArmorClass(Integer.parseInt((element
							.getChildText("AC"))));
					monster.setFortitude(Integer.parseInt((element
							.getChildText("Fortitude"))));
					monster.setReflex(Integer.parseInt((element
							.getChildText("Reflexes"))));
					monster.setWill(Integer.parseInt((element
							.getChildText("Will"))));
					String[] temp = ((element.getChildText("AttackBase"))).split("/");
					int[] atk = new int[temp.length];
					for (int index = 0; index < temp.length; index++) {
						atk[index] = Integer.parseInt(temp[index]);
					}
					monster.setAttackBase(atk);
					monster.setLoot(Loot);
					monster.setAttacks(powers);
					xmlMonster.put(monster.getName(), monster);
					XMLin.close();
				}
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static void addDNDMonster(Monster monster) {
		// Lendo o XML

		try {
			FileInputStream XMLin = new FileInputStream("monsters.xml");
			SAXBuilder sb = new SAXBuilder();

			try {
				Document doc = sb.build(XMLin);
				// Recuperamos o elemento root
				Element xmlMonsters = doc.getRootElement();

				Element newMonster = new Element("Monster");

				Element Race = new Element("Race");
				Race.addContent(monster.getRace());
				newMonster.addContent(Race);

				Element Name = new Element("Name");
				Name.addContent(monster.getName());
				newMonster.addContent(Name);
				Element Alignment = new Element("Alignment");
				Alignment.addContent(monster.getAlignment().name());
				newMonster.addContent(Alignment);

				Element Size = new Element("Size");
				Size.addContent(monster.getSize().name());
				newMonster.addContent(Size);

				Element LifePoints = new Element("LifePoints");
				LifePoints.addContent("" + monster.getLifePoints());
				newMonster.addContent(LifePoints);

				Element Moviments = new Element("Moviments");
				Moviments.addContent("" + monster.movs);
				newMonster.addContent(Moviments);

				Element Challenge = new Element("Challenge");
				Challenge.addContent("" + monster.getChallenge());
				newMonster.addContent(Challenge);

				Element Initiative = new Element("Initiative");
				Initiative.addContent("" + monster.getInitiative());
				newMonster.addContent(Initiative);

				Element AC = new Element("AC");
				AC.addContent("" + monster.getArmorClass());
				newMonster.addContent(AC);

				Element Fortitude = new Element("Fortitude");
				Fortitude.addContent(""+monster.getFortitude());
				newMonster.addContent(Fortitude);

				Element Reflexes = new Element("Reflexes");
				Reflexes.addContent("" + monster.getReflex());
				newMonster.addContent(Reflexes);

				Element Will = new Element("Will");
				Will.addContent("" + monster.getWill());
				newMonster.addContent(Will);

				Element AttackBase = new Element("AttackBase");
				String temp = "";
				for (int atk : monster.getAttackBase()) {
					temp = temp +"/"+ atk;
				}
				AttackBase.addContent(temp);
				newMonster.addContent(AttackBase);

				Element Loots = new Element("Loots");
				for (Item loot : monster.getLoot()) {
					Element Loot = new Element("Loot");
					Element Item = new Element("Item");
					Item.addContent(loot.getName());
					Element Quantity = new Element("Quantity");
					Quantity.addContent("" + loot.getQuantity());
					Loot.addContent(Item);
					Loot.addContent(Quantity);
					Loots.addContent(Loot);
				}
				newMonster.addContent(Loots);

				Element Powers = new Element("Powers");
				for (String power : monster.getAttacks()) {
					Element Power = new Element("Power");
					Element Name1 = new Element("Name");
					String[] splited = power.split(" -- ");
					Name1.addContent(splited[0]);
					Element Description = new Element("Description");
					Description.addContent(splited[1]);
					Power.addContent(Name1);
					Power.addContent(Description);
					Powers.addContent(Power);
				}
				newMonster.addContent(Powers);
				xmlMonsters.addContent(newMonster);

				// serialize it onto System.out

				// Imprimindo o XML
				XMLOutputter xout = new XMLOutputter();
				try {
					FileOutputStream XML = new FileOutputStream("monsters.xml");
					try {
						xout.output(doc, XML);
						XML.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		loadDNDMonsters();
	}

	public static void removeDNDMonster(Monster monster) {
		// Lendo o XML
		
		try {
			FileInputStream XMLin = new FileInputStream("monsters.xml");
			SAXBuilder sb = new SAXBuilder();

			try {
				Document doc = sb.build(XMLin);
				// Recuperamos o elemento root
				Element xmlMonsters = doc.getRootElement();
				List elements = xmlMonsters.getChildren();
				Iterator i = elements.iterator();
				int toRemove = 0;
				while (i.hasNext()) {
					Element element = (Element) i.next();
					String name = element.getChildText("Name");
					if (name.equals(monster.getName())) {
						xmlMonsters.removeContent(toRemove);
						break;
					}
					toRemove++;
				}
				try {
					XMLin.close();
				} catch (Exception e) {
					// TODO: handle exception
				}
				// serialize it onto System.out

				// Imprimindo o XML
				XMLOutputter xout = new XMLOutputter();
				try {
					FileOutputStream XML = new FileOutputStream("monsters.xml");
					try {
						xout.output(doc, XML);
						XML.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		loadDNDMonsters();
	}
	
}
